const log4js = require('log4js');
const mysql = require('mysql');
const {Util, Type} = require('dob_common');
const {Pool} = require('dob_pool');
const Connect = require('./Connect');
const MysqlError = require('./Error');

const logger = log4js.getLogger();
const poolObject = {};

class Manage {
  static async createConnectPoll(name, host, user, password, database, connectNumber = 4) {
    if(Type.isString(name) === false) {
      throw new MysqlError(MysqlError.NAME_PARAM_INVALID);
    }

    if(Number.isInteger(connectNumber) === false || connectNumber < 1 || connectNumber > 16) {
      throw new MysqlError(MysqlError.CONNECT_NUMBER_PARAM_INVALID);
    }

    let pool = poolObject[name];

    if(pool !== void 0) {
      throw new MysqlError(MysqlError.POOL_EXIST);
    }

    pool = {
      number: 0,
      pool: new Pool(Connect)
    };

    for(let i = 0; i < connectNumber; i++) {
      let connect = new Connect(host, user, password, database);

      try {
        await connect.connect();
        pool.pool.push(connect);
        pool.number++;
      }
      catch(error) {
        logger.error(error);
      }
    }

    poolObject[name] = pool;
  }

  static getConnectPool(name) {
    if(Type.isString(name) === false) {
      throw new MysqlError(MysqlError.NAME_PARAM_INVALID);
    }

    let pool = poolObject[name];

    if(pool === void 0) {
      throw new MysqlError(MysqlError.POOL_NOT_EXIST);
    }

    return pool.pool;
  }

  static async destoryConnectPool(name) {
    let pool = poolObject[name];

    while(pool.number > 0) {
      let connect = await pool.pool.pop();
      connect.disconnect();
      pool.number--;
      Util.sleep(100);
    }
  }

  static async destoryAllConnectPool() {
    for(let key in poolObject) {
      await this.destoryConnectPool(key);
    }
  }

  static raw(value) {
    return mysql.raw(value);
  }
}

module.exports = Manage;